package com.bingxue.edu.migration.pay;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import com.bingxue.edu.common.enums.PayTypeEnum;
import com.bingxue.edu.framework.common.util.CheckUtils;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.framework.mybatis.base.BaseService;
import com.bingxue.edu.management.shop.model.query.PayResultQuery;
import com.bingxue.edu.management.shop.model.req.FuiouPayOrderCreateReq;
import com.bingxue.edu.management.shop.service.FuiouPayService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;

/**
 * 临时支付记录业务实现类
 *
 * @author panbo
 * @since 2024/09/19 14:16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TempPayRecordService extends BaseService<TempPayRecordMapper, TempPayRecord> {

    private final FuiouPayService fuiouPayService;

    /**
     * 创建续报支付订单
     */
    public JSONObject createPayOrder(TempPayRecordReq req) {
        TempPayRecord record = this.copy(req);
        record.setPayOff(false);
        record.setPayType(PayTypeEnum.FUIOU);
        record.setEnrollStatusUpdated(false);
        record.setRefunded(false);
        record.setFinAccountId(PayTypeEnum.FUIOU.getValue());
        this.save(record);

        FuiouPayOrderCreateReq fuiouPayOrderCreateReq = new FuiouPayOrderCreateReq();
        fuiouPayOrderCreateReq.setOrderId(record.getId());
        fuiouPayOrderCreateReq.setOrderDate(record.getCreateTime());
        fuiouPayOrderCreateReq.setOrderAmount(req.getActualTotalPrice());
        fuiouPayOrderCreateReq.setGoodsName("2024秋下续报-" + req.getClassName());
        fuiouPayOrderCreateReq.setGoodsDetail(fuiouPayOrderCreateReq.getGoodsName());
        fuiouPayOrderCreateReq.setOpenid(req.getOpenid());
        fuiouPayOrderCreateReq.setBackNotifyUrl("https://edu.bingxuewenhua.com/api/temp/pay/callback");

        if (req.getDebug() != null && req.getDebug()) {
            fuiouPayOrderCreateReq.setOrderAmount(BigDecimal.valueOf(0.01));
        }
        JSONObject payOrderResult = fuiouPayService.createPayOrder(fuiouPayOrderCreateReq);
        log.info("创建续报支付订单成功, {}", req);
        return payOrderResult.getJSONObject("order_info");
    }

    /**
     * 查询支付结果
     */
    public JSONObject queryPayResult(String orderId) {
        TempPayRecord record = this.getById(orderId);
        ValidationUtils.throwIfNull(record, "订单不存在");
        PayResultQuery query = new PayResultQuery();
        query.setOrderId(orderId);
        query.setOrderDate(record.getCreateTime());
        JSONObject message = fuiouPayService.queryPayResult(query);
        log.info("查询支付结果, {}", message);
        completePay(message);
        return message;
    }

    /**
     * 完成支付回调
     */
    public void completePay(JSONObject message) {
        String orderId = message.getStr("order_id");
        String orderSt = message.getStr("order_st");
        String ourTradeNo = message.getStr("fy_order_id");
        if (!orderSt.equals("1")) {
            log.info("支付回调跳过, 支付失败或未支付, orderId: {}", orderId);
            return;
        }
        TempPayRecord record = this.getById(orderId);
        if (record == null) {
            log.warn("支付回调出错, 订单不存在, orderId: {}", orderId);
            return;
        }
        record.setPayOff(true);
        record.setPayTime(LocalDateTime.now());
        record.setOutTradeNo(ourTradeNo);
        record.setEnrollStatusUpdated(true);
        // 远程调用设置下半期续报状态
        try {
            String response = HttpUtil.post("https://www.bingxuewenhua.com/api/temp/setNextPeriodEnrolled/" + record.getClassStudentId(), new HashMap<>());
            JSONObject result = new JSONObject(response);
            CheckUtils.throwIfNotEqual(result.getInt("code"), 0, "远程调用出错");
        } catch (Exception e) {
            log.error("远程调用设置下半期续报失败", e);
            record.setEnrollStatusUpdated(false);
        }
        this.updateById(record);
        log.info("支付回调完成, orderId: {}, update status: {}", orderId, record.getEnrollStatusUpdated());
    }
}
